package com.acwing.partition3;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author `RKC`
 * @date 2021/12/19 15:56
 */
public class AC292炮兵阵地 {

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
        String[] s = reader.readLine().split("\\s+");
        int n = Integer.parseInt(s[0]), m = Integer.parseInt(s[1]);
        int[] graph = new int[n + 3];
        for (int i = 1; i <= n; i++) {
            String str = reader.readLine();
            for (int j = 0; j < m; j++) {
                graph[i] += str.charAt(m - j - 1) == 'H' ? 1 << j : 0;
            }
        }
        writer.write(String.valueOf(dynamicProgramming(n, m, graph)));
        writer.flush();
    }

    private static int dynamicProgramming(int n, int m, int[] graph) {
        //存储状态key能转移到的合法状态value
        Map<Integer, List<Integer>> statusMap = new HashMap<>();
        //找出所有单行合法状态
        for (int i = 0; i < 1 << m; i++) {
            if ((i & (i << 1)) == 0 && (i & (i << 2)) == 0) {
                statusMap.put(i, new ArrayList<>());
            }
        }
        //找出所有单行合法状态的合法转移
        for (int curr : statusMap.keySet()) {
            List<Integer> status = statusMap.get(curr);
            for (int prev1 : statusMap.keySet()) {
                if ((curr & prev1) == 0) status.add(prev1);
            }
        }
        //dp[[i][j][k]遍历到了第i行，当前行的状态是j，上一行的状态是k的最大合法方案
        int[][][] dp = new int[2][1 << m][1 << m];
        for (int i = 1; i <= n; i++) {
            for (int curr : statusMap.keySet()) {
                if ((curr & graph[i]) != 0) continue;
                int count = Integer.bitCount(curr);
                for (int prev1 : statusMap.get(curr)) {
                    for (int prev2 : statusMap.get(prev1)) {
                        if ((curr & prev2) != 0) continue;
                        dp[i & 1][curr][prev1] = Math.max(dp[i & 1][curr][prev1], dp[i - 1 & 1][prev1][prev2] + count);
                    }
                }
            }
        }
        int answer = 0;
        for (int curr : statusMap.keySet()) {
            for (int prev1 : statusMap.get(curr)) {
                answer = Math.max(answer, dp[n & 1][curr][prev1]);
            }
        }
        return answer;
    }
}
